#include "rtc.h"
#include "time.h"
#include "pixelwifi.h"

RtcDS1307<TwoWire> Rtc(Wire);
RtcDateTime ds1307;
RTC rtc;

uint8_t time_set = 0, time_sync = 0, force_update = 0;
const char *monthName[12] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 8*3600;
const int   daylightOffset_sec = 0;

struct tm time_info;

void rtcInit(void)
{
    if(!Rtc.GetIsRunning())        
        Rtc.SetIsRunning(true);
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}

void ntpTask(void)
{
    static uint8_t fail_cnt = 0;
    static uint16_t cnt = 0, force_update = 0;

    if(WIFI_STATE)
    {
        if(cnt%600==0 || force_update==1)
        {
            force_update = 0;
            cnt = 0;
            // Serial.println("Sync start");
            if(getLocalTime(&time_info) == false)
            {
                fail_cnt++;
                if(fail_cnt < 10)
                    force_update = 1;
                else
                    fail_cnt = 0;
                Serial.println("time sync failed");
            }
            else
            {
                rtc.year = (byte)((time_info.tm_year+1900)%100);
                rtc.month = (byte)(time_info.tm_mon+1);
                rtc.date = (byte)time_info.tm_mday;
                rtc.week = (byte)time_info.tm_wday;
                rtc.hour = (byte)time_info.tm_hour;
                rtc.min = (byte)time_info.tm_min;
                rtc.sec = (byte)time_info.tm_sec;
                time_set = 1;
            }
        }
        cnt++;
    }
    else
    {
        cnt = 0;
        force_update = 0;
        fail_cnt = 0;
    }
}

uint8_t isTimeValid(void)
{
    if(ds1307.Year() > 2199)
        return YEAR_INVALID;
    else if(ds1307.Month() > 12)
        return MONTH_INVALID;
    else if(ds1307.Day() > 31)
        return DATE_INVALID;
    else if(ds1307.DayOfWeek() > 7)
        return WEEK_INVALID;
    else if(ds1307.Hour() > 23)
        return HOUR_INVALID;
    else if(ds1307.Minute() > 59)
        return MIN_INVALILD;
    else if(ds1307.Second() > 59)
        return SEC_INVALID;
    else
        return NONE_INVALID;
}

void rtcTask(void)
{
        String date_str;
        String time_str;
        uint8_t error_val = 5;

        if(time_set)
        {
            time_set = 0;
            date_str = String(monthName[rtc.month-1]) + " " + String(rtc.date/10) + String(rtc.date%10) + " " + "20" + String(rtc.year);
            time_str = String(rtc.hour/10) + String(rtc.hour%10) + ":" + String(rtc.min/10) + String(rtc.min%10) + ":" + String(rtc.sec/10) + String(rtc.sec%10);
            Serial.print(date_str);
            Serial.println(time_str);
            RtcDateTime s_time = RtcDateTime(date_str.c_str(), time_str.c_str());
            Rtc.SetDateTime(s_time);
        }

        do
        {
            ds1307 = Rtc.GetDateTime();
            error_val-- ;    
        } while (isTimeValid() && error_val!=0);

        rtc.year = ds1307.Year();
        rtc.month = ds1307.Month();
        rtc.date = ds1307.Day();
        rtc.week = ds1307.DayOfWeek();
        rtc.hour = ds1307.Hour();
        rtc.min = ds1307.Minute();
        rtc.sec = ds1307.Second();
}
